package com.jwaoo.chat.data.db;

import android.content.Context;
import android.content.Intent;
import com.dx.as.JWCache;
import com.dx.as.common.CommonUtils;
import com.dx.as.common.ILoadListener;
import com.dx.as.common.string.StringUtil;
import com.dx.as.db.IDBListener;
import com.dx.as.db.SqlLiteHelper;
import com.dx.as.upload.DownloadFile;
import com.dx.as.upload.DownloadInfo;
import com.dx.as.upload.ProgressRequestBody;
import com.dx.as.upload.UploadFile;
import com.jwaoo.chat.ChatConstants;
import com.jwaoo.chat.ChatHelpter;
import com.jwaoo.chat.IMessageClient;
import com.jwaoo.chat.Message;
import com.jwaoo.chat.UserInfo;
import com.jwaoo.chat.activity.module.fromapp.AppInstance;
import com.jwaoo.chat.attachment.FileAttachment;
import com.jwaoo.chat.fragment.session.bean.SessionBean;
import com.jwaoo.chat.session.Extras;
import com.jwaoo.chat.session.avchat.AVChatType;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by jwaoo on 2017/7/4.
 */

public class MessageHandler {
    public final static int GET_SESSION = 0;
    public final static int GET_ALL_MESSAGE_BY_ID = 1;
    public final static int GET_MESSAGE = 2;
    public final static int SAVE_MESSAGE = 3;
    public final static int UPDATE_MESSAGE = 5;
    public final static int UPDATE_SESSION = 6;
    public final static int GET_MESSAGE_IMG = 7;
    public final static int DELETE_MESSAGE = 8;
    public final static int DELETE_ALL_MESSAGE = 9;
    private static MessageHandler messageHandler;
    private IMessageClient client;
    private Context mContext;
    private Map<Integer,Message> downloadMap = new HashMap<>();
    private MessageHandler(Context context){
        this.mContext = context;
    }

    public static synchronized MessageHandler getInstace(Context context){
        if (messageHandler == null){
            synchronized (MessageHandler.class){
                if (messageHandler == null){
                    messageHandler = new MessageHandler(context);
                }
            }
        }
        return messageHandler;
    }

    public void setIMessageClient(IMessageClient client){
        this.client = client;
    }

    public void getSessions(ChatDatabase database , ILoadListener loadListener){
        List<SessionBean> sessionList = database.dbMsgDao().queryAllSession();
        loadListener.onResponse(sessionList,0);
    }

    public void updateSession(ChatDatabase database ,SessionBean sessionBean){
        database.dbMsgDao().updateSession(sessionBean);
    }

    private void updateMessage(ChatDatabase database,Message message){
        database.dbMsgDao().updateMessage(message);
    }

    private void deleteMessage(ChatDatabase database,Message message){
        List<Message> list = new ArrayList<>(1);
        list.add(message);
        database.dbMsgDao().deleteMessage(list);
        List<Message> msgs = database.dbMsgDao().queryMessage(message.getFriend(),0);
        if (msgs != null && msgs.size() > 0){
            SessionBean sessionBean = getSession(msgs.get(0));
            database.dbMsgDao().updateSession(sessionBean);
        }

    }

    private void deleteAllMessage(ChatDatabase database,List<Message> messages){
        database.dbMsgDao().deleteMessage(messages);
        SessionBean sessionBean = database.dbMsgDao().querySessionUnReadCount(messages.get(0).getFriend());
        database.dbMsgDao().deleteSession(sessionBean);
    }

    public void getMessages(ChatDatabase database,int uuid,long time ,ILoadListener loadListener){
        List<Message> list = null;
        if (time == 0)
                list = database.dbMsgDao().queryMessage(uuid);
        else
            list = database.dbMsgDao().queryMessage(uuid,time);
        loadListener.onResponse(list,0);
    }

    public void getAllMessagesById(ChatDatabase database,int uuid,ILoadListener loadListener){
        List<Message> list = null;
        list = database.dbMsgDao().queryAllMessageByID(uuid);
        loadListener.onResponse(list,0);
    }

    public void getMessagesWithIMG(ChatDatabase database,int friend,ILoadListener loadListener){
        List<Message> list = null;
        list = database.dbMsgDao().queryMessageWithIMG(friend,ChatConstants.image);
        loadListener.onResponse(list,0);
    }

    public void saveMessage(ChatDatabase database,Message message){
        Message msg = database.dbMsgDao().queryMesaage(message.getMsgid());
        if (msg != null){
            database.dbMsgDao().updateMessage(message);
        }else {
            database.dbMsgDao().insertMessage(message);
            sendSessionBroad();
        }
        SessionBean unRead = database.dbMsgDao().querySessionUnReadCount(message.getFriend());
        SessionBean sessionBean = getSession(message);
        if (unRead != null){
            if (ChatHelpter.currentSessionId != message.getFriend()) {
                sessionBean.setUnReadCount(unRead.getUnReadCount() + 1);
            }
            if (sessionBean.getDirect() == ChatConstants.Out){
                sessionBean.setNickName(unRead.getNickName());
            }
            database.dbMsgDao().updateSession(sessionBean);
        }else {
            if (ChatHelpter.currentSessionId != message.getFriend())
                sessionBean.setUnReadCount(1);
            database.dbMsgDao().insertSession(sessionBean);
        }

    }
    private void sendSessionBroad(){
        //发送信息
        Intent intentSession = new Intent();
        intentSession.setAction(ChatConstants.ACTION);
        JWCache.getContext().sendBroadcast(intentSession);
    }

    public void updateUnReadMessage(){
        handlerMessages(GET_SESSION, new ILoadListener<List<SessionBean>>() {
            @Override
            public void onResponse(List<SessionBean> response, int flg) {
                if (response != null && !response.isEmpty()){
                    int sum = 0;
                    for (SessionBean sessionBean : response){
                        sum += sessionBean.getUnReadCount();
                    }
                    if (sum > 0) AppInstance.getInstance().updateUnReadCount(1,false);
                }
            }

            @Override
            public void onFailure(Throwable t) {

            }
        });
    }

    /**
     * 第一个参数 ： what 执行的操作
     * 第二个参数 ：
     * @param objects
     */
    public void handlerMessages(final Object ... objects){
        SqlLiteHelper.getInstance(mContext).dbOption(ChatDatabase.class,new IDBListener<ChatDatabase>(){
            @Override
            public void onOption(ChatDatabase database) {
                int what = Integer.valueOf(objects[0].toString());
                switch (what){
                    case GET_SESSION:
                        ILoadListener loadListener = (ILoadListener) objects[1];
                        getSessions(database,loadListener);
                        break;
                    case GET_MESSAGE:
                        int id = Integer.parseInt(objects[1].toString());
                        ILoadListener loadListenerMsg = (ILoadListener) objects[2];
                        long time = (Long) objects[3];
                        getMessages(database,id,time,loadListenerMsg);
                        break;
                    case SAVE_MESSAGE:
                        Message message = (Message) objects[1];
                        saveMessage(database,message);
                        if (message.getMsgtype() == ChatConstants.audio
                                || (message.getMsgtype() == ChatConstants.video && message.getSnap() == ChatConstants.snap)
                                || (message.getMsgtype() == ChatConstants.image && message.getSnap() == ChatConstants.snap)){
                            handlerAttachmentMessage(message);
                        }
                        break;
                    case UPDATE_MESSAGE:
                        Message message1 = (Message) objects[1];
                        updateMessage(database,message1);
                        break;
                    case UPDATE_SESSION:
                        SessionBean sessionBean = (SessionBean) objects[1];
                        updateSession(database,sessionBean);
                        break;
                    case GET_MESSAGE_IMG:
                        int friend = Integer.parseInt(objects[1].toString());
                        ILoadListener iLoadListener = (ILoadListener) objects[2];
                        getMessagesWithIMG(database,friend,iLoadListener);
                        break;
                    case DELETE_MESSAGE:
                        Message message2 = (Message) objects[1];
                        deleteMessage(database,message2);
                        break;
                    case GET_ALL_MESSAGE_BY_ID:
                        int friendId = Integer.parseInt(objects[1].toString());
                        ILoadListener loadListener2 = (ILoadListener) objects[2];
                        getAllMessagesById(database,friendId,loadListener2);
                        break;
                    case DELETE_ALL_MESSAGE:
                        List<Message> list = (List<Message>)objects[1];
                        deleteAllMessage(database,list);
                        break;
                }
            }
        },true);
    }

    public boolean sendMessage(Message message){
        String json = createJson(message);
        if (this.client == null)  return false;
         return this.client.sendMessage(message,json);
    }

    public Message createMessage(Object ... objects) {

        Message message = getBaseMessage();
        int msgType = Integer.parseInt(objects[0].toString());
        int friend = Integer.parseInt(objects[1].toString());

        switch (msgType){
            case ChatConstants.text:
                String content = objects[2].toString();
                message.setContent(content);
                break;
            case ChatConstants.audio:
            case ChatConstants.video:
            case ChatConstants.image:
            case ChatConstants.audio_chat:
            case ChatConstants.video_chat:
                FileAttachment fileAttachment = (FileAttachment)objects[2];
                message.setAttachment(fileAttachment);
                break;
            default:
                break;
        }
        message.setMsgtype(msgType);
        message.setFriend(friend);
        handlerMessages(SAVE_MESSAGE,message);
        return message;
    }

    private Message getBaseMessage(){
        Message message = new Message();
        int _id = (int)System.currentTimeMillis();
        message.setMsgid(_id);
        message.setTimestamp(System.currentTimeMillis());
        message.setState(ChatConstants.sending);
        message.setSessiontype(ChatConstants.CHAT);
        message.setDirect(ChatConstants.Out);
        return message;
    }

    private SessionBean getSession(Message message){
        SessionBean sessionBean = new SessionBean();
        sessionBean.setMsgtype(message.getMsgtype());
        sessionBean.setContent(message.getContent());
        sessionBean.setNickName(message.getNickname());
        sessionBean.setSessiontype(message.getSessiontype());
        sessionBean.setTimestamp(message.getTimestamp());
        sessionBean.setFriend(message.getFriend());
        sessionBean.setDirect(message.getDirect());
        if (message.getMsgtype() != ChatConstants.text)
            sessionBean.setSnap(message.getSnap());
        return sessionBean;
    }

    private String createJson(Message message){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("{");
        stringBuffer.append("\"sessiontype\":");
        stringBuffer.append(message.getSessiontype());
        stringBuffer.append(",");
        stringBuffer.append("\"msgtype\":");
        stringBuffer.append(message.getMsgtype());
        stringBuffer.append(",");
        stringBuffer.append("\"nickname\":");
        stringBuffer.append("\""+ AppInstance.getInstance().getIMName()+"\"");
        stringBuffer.append(",");
        stringBuffer.append("\"msgid\":");
        stringBuffer.append(message.getMsgid());
        stringBuffer.append(",");
        stringBuffer.append("\"friend\":");
        stringBuffer.append(AppInstance.getInstance().getIMAcount());
        stringBuffer.append(",");
        stringBuffer.append("\"content\":");
        stringBuffer.append("\""+message.getContent()+"\"");

        stringBuffer.append(",");
        stringBuffer.append("\"snap\":");
        stringBuffer.append(message.getSnap());

        if (message.getMsgtype() == ChatConstants.text){
            stringBuffer.append("}");
            return stringBuffer.toString();
        }

        stringBuffer.append(",");
        stringBuffer.append("\"attachment\":");
        stringBuffer.append("{");
        if (message.getMsgtype() == ChatConstants.audio){
            stringBuffer.append("\"url\":");
            stringBuffer.append("\""+message.getAttachment().getUrl()+"\"");
            stringBuffer.append(",");
            stringBuffer.append("\"duration\":");
            stringBuffer.append(message.getAttachment().getDuration());
        }else if (message.getMsgtype() == ChatConstants.video || message.getMsgtype() == ChatConstants.image){
            stringBuffer.append("\"height\":");
            stringBuffer.append(message.getAttachment().getHeight());
            stringBuffer.append(",");
            stringBuffer.append("\"width\":");
            stringBuffer.append(message.getAttachment().getWidth());
            stringBuffer.append(",");
            stringBuffer.append("\"url\":");
            stringBuffer.append("\""+message.getAttachment().getUrl()+"\"");
            stringBuffer.append(",");
            stringBuffer.append("\"thumbnail\":");
            stringBuffer.append("\""+message.getAttachment().getThumbnail()+"\"");
        }else if (message.getMsgtype() == AVChatType.AUDIO.getValue() || message.getMsgtype() == AVChatType.VIDEO.getValue()){
            stringBuffer.append("\"attachstate\":");
            stringBuffer.append(message.getAttachment().getAttachstate());
            stringBuffer.append(",");
            stringBuffer.append("\"roomid\":");
            stringBuffer.append("\""+message.getAttachment().getRoomid()+"\"");
        }
        stringBuffer.append("}}");
        return stringBuffer.toString();
    }

    public void uploadAttachmentMessage(final Message message){
        final Map<String,Object> parm = new HashMap<>();
        parm.put("as","pub");
        parm.put("flag","zoom");
        if (message.getMsgtype() == ChatConstants.video){
            parm.put("type","video");
            parm.put("end",".mp4");
            parm.put("media_type","video/mp4");
            File file = new File(message.getAttachment().getPath());
            doUpload(file,message,parm);

            String btmPath = message.getAttachment().getThumbnail();
            if (StringUtil.isEmpty(btmPath)) btmPath = CommonUtils.getFilePath(CommonUtils.getImgDir(mContext),message.getAttachment().getPath());
            File file1 = new File(btmPath);
            message.getAttachment().setThumbnail("");
            parm.put("type","img");
            parm.put("end",".jpg");
            parm.put("media_type","image/jpg");
            doUpload(file1,message,parm);

        }else if (message.getMsgtype() == ChatConstants.image){
            File file1 = new File(message.getAttachment().getPath());
            message.getAttachment().setThumbnail("");
            parm.put("type","img");
            parm.put("end",".jpg");
            parm.put("media_type","image/jpg");
            doUpload(file1,message,parm);
        }
        downloadMap.put(message.getMsgid(),message);
    }

    private void doUpload(File file,final Message message,Map<String,Object> parm){

        DownloadInfo downloadInfo = new DownloadInfo(){
            @Override
            public void onDownLoadSuccess() {
                super.onDownLoadSuccess();
                handlerMessages(UPDATE_MESSAGE,downloadMap.get(this.getMsgId()));
            }

            @Override
            public void onDownLoadFailed() {
                super.onDownLoadFailed();
                downloadMap.get(this.getMsgId()).getAttachment().setAttachstate(ChatConstants.fail);
                handlerMessages(UPDATE_MESSAGE,downloadMap.get(this.getMsgId()));
//                    sendUpdateMessageBroad(downloadMap.get(this.msgId));
            }

            @Override
            public void onDownProgress(long progress, long total) {
                super.onDownProgress(progress, total);
            }

            @Override
            public int getMsgId() {
                return message.getMsgid();
            }
        };

        UploadFile.uploadFile(parm,file , new ILoadListener() {
            @Override
            public void onResponse(Object response, int flg) {
                if (response != null){
                    Map<String,String> result = (Map<String, String>) response;
                    String url = result.get("path");
                    if (message.getMsgtype() == ChatConstants.video || message.getMsgtype() == ChatConstants.image){

                        if (result.containsKey("smallPath")) {
                            message.getAttachment().setThumbnail(result.get("smallPath"));
                            if (message.getMsgtype() == ChatConstants.image){
                                message.getAttachment().setAttachstate(ChatConstants.transferred);
                                message.getAttachment().setUrl(url);
                            }
                        }else {
                            message.getAttachment().setAttachstate(ChatConstants.transferred);
                            message.getAttachment().setUrl(url);
                        }
                        if (!StringUtil.isEmpty(message.getAttachment().getUrl()) && !StringUtil.isEmpty(message.getAttachment().getThumbnail())){
                            sendMessage(message);
                            return;
                        }
                    }else{
                        message.getAttachment().setAttachstate(ChatConstants.transferred);
                        message.getAttachment().setUrl(url);
                        sendMessage(message);
                    }
                }
            }

            @Override
            public void onFailure(Throwable t) {
                message.getAttachment().setAttachstate(ChatConstants.fail);
                handlerMessages(UPDATE_MESSAGE,message);
            }
        },new ProgressRequestBody(file,message.getMsgid(),downloadInfo));
        downloadMap.put(message.getMsgid(),message);
    }


    public void handlerAttachmentMessage(final Message message){
        if ( StringUtil.isEmpty(message.getAttachment().getPath()) || message.getAttachment().getAttachstate() == ChatConstants.fail){
            String dir = "";
            if (message.getMsgtype() == ChatConstants.audio){
                dir = CommonUtils.getAudioDir(mContext);
            }else if (message.getMsgtype() == ChatConstants.video){
                dir = CommonUtils.getVideoDir(mContext);
            }else if (message.getMsgtype() == ChatConstants.image || message.getMsgtype() == ChatConstants.snap){
                dir = CommonUtils.getImgDir(mContext);
            }
            DownloadInfo downloadInfo = new DownloadInfo(){
                @Override
                public void onDownLoadSuccess() {
                    super.onDownLoadSuccess();
                    downloadMap.get(this.getMsgId()).getAttachment().setAttachstate(ChatConstants.transferred);
                    handlerMessages(UPDATE_MESSAGE,downloadMap.get(this.getMsgId()));
                    sendMessageBroad(downloadMap.get(this.getMsgId()));
                }

                @Override
                public void onDownLoadFailed() {
                    super.onDownLoadFailed();
                    downloadMap.get(this.getMsgId()).getAttachment().setAttachstate(ChatConstants.fail);
                    handlerMessages(UPDATE_MESSAGE,downloadMap.get(this.getMsgId()));
                    sendMessageBroad(downloadMap.get(this.getMsgId()));
                }

                @Override
                public void onDownProgress(long progress, long total) {
                    super.onDownProgress(progress, total);
                }

                @Override
                public int getMsgId() {
                    return message.getMsgid();
                }
            };

            String path = getFilePath(dir,message.getAttachment().getUrl());
            message.getAttachment().setPath(path);
            downloadMap.put(message.getMsgid(),message);
            new DownloadFile().doDownLoad(message.getMsgid(),message.getAttachment().getUrl(),path,downloadInfo);
        }
    }

    public String getFilePath(String dir,String url){
        if (StringUtil.isEmpty(url)) return null;
        return dir + url.substring(url.lastIndexOf("/")+1,url.lastIndexOf("."));
    }

    public void sendMessageBroad(Message message){
        Intent intentMessage = new Intent();
        intentMessage.setAction(ChatConstants.ACTION_MESSAGE);
        intentMessage.putExtra(Extras.EXTRA_MESSAGE,message);
        ChatHelpter.getContext().sendBroadcast(intentMessage);
    }

}
